import sys
import pdb
import threading
import heartbeating
import MSSafeinsideLib as lib
log = lib.log
g_name = 'ms driver'
CONFIG_NAME = 'spectech89_config.cfg'

log.info(g_name + ' starting as %s' % (str(sys.argv)))

try:
    heartbeat = heartbeating.HeartbeatListener(int(lib.MSConfig.getConfig(CONFIG_NAME).get('main', 'heartbeat_port')))
    heartbeat.start()
except Exception, err:
    log.error('can\'t start ' + g_name + ' at port ' + lib.MSConfig.getConfig(CONFIG_NAME).get('main', 'heartbeat_port') + ', probably another instance is running')
    log.error('code: %s', str(err))
    sys.exit(1)

def processAPIObjects(isTerminated, dummy):
    log.info('processAPIObjects: started')

    try:
        cfg = lib.MSConfig.getConfig(CONFIG_NAME)
        reader = lib.MSAPIReader(cfg.get('msapi', 'url'))
        writer = lib.MSSochiWriter(cfg.get('sochi', 'url'),
                                   cfg.get('sochi', 'username'),
                                   cfg.get('sochi', 'password'))
    except Exception, err:
        log.info('processAPIObjects: can\'t start: %s', str(err))
        return

    objects = {}
    ctr = 0
    lastEventId = 0

    try:
        while not isTerminated.isSet():
            if (ctr % 100 == 0):
                try:
                    lib.MSObjects.readObjectsFromFile(cfg.get('msapi', 'objects_cfg'), objects)
                    log.info('processAPIObjects: loaded %d objects from %s', len(objects), cfg.get('msapi', 'objects_cfg'))
                except Exception, err:
                    log.error('processAPIObjects: can\'t load objects: %s', str(err))
                log.info('processAPIObjects: status format: all:pgsm:cid:written')
            allevents = []
            written = 0
            try:
                eventsGPS = reader.getEventsGPS_ForSochi(objects)
                allevents += eventsGPS
            except Exception, err:
                log.error('processAPIObjects: can\'t read events: %s', str(err))

            try:
                written = writer.writeEventsMobile(allevents)
            except Exception, err:
                log.error('processAPIObjects: can\'t write events: %s', str(err))

            log.info('processAPIObjects: %d:%d', len(allevents), written)
            ctr += 1
            lib.time.sleep(10)
    except Exception, err:
        log.error('processAPIObjects: fatal error: %s' % (str(err)))

def processSOSofOne(isTerminated, dummy):
    log.info('processSOS: started')

    try:
        cfg = lib.MSConfig.getConfig(CONFIG_NAME)
        reader = lib.MSAPIReader(cfg.get('msapi', 'url'))
        writer = lib.MSSochiWriter(cfg.get('sochi', 'url'),
                                   cfg.get('sochi', 'username'),
                                   cfg.get('sochi', 'password'))
    except Exception, err:
        log.info('processSOS: can\'t start: %s', str(err))
        return

    requiredIds = [63743556]
    objects = {}
    ctr = 0
    lastEventId = 0

    try:
        while not isTerminated.isSet():
            if (ctr % 100 == 0):
                try:
                    lib.MSObjects.readObjectsFromFile(cfg.get('msapi', 'objects_cfg'), objects)
                    nobjects = {}
                    for k,v in objects.iteritems():
                        if k in requiredIds:
                            nobjects[k] = v
                    objects = nobjects

                    log.info('processSOS: loaded %d objects from %s', len(objects), cfg.get('msapi', 'objects_cfg'))
                except Exception, err:
                    log.error('processSOS: can\'t load objects: %s', str(err))
                log.info('processSOS: status format: all:pgsm:cid:written')

            allevents = []
            written = 0
            try:
                eventsGPS = reader.getEventsSOS_ForSochi(objects)
                allevents += eventsGPS
            except Exception, err:
                log.error('processSOS: can\'t read events: %s', str(err))

            try:
                written = writer.writeEventsMobile(allevents)
            except Exception, err:
                log.error('processSOS: can\'t write events: %s', str(err))

            log.info('processSOS: %d:%d', len(allevents), written)
            ctr += 1
            lib.time.sleep(10)
    except Exception, err:
        log.error('processSOS: fatal error: %s' % (str(err)))


log.info('starting threads... ')
isTerminated = threading.Event()
isTerminated.clear()

normalObjectsFromMSAPI  = threading.Thread(target=processAPIObjects, name='normalObjectsFromMSAPI', args=(isTerminated, None))
sosObjectsFromMSAPI  = threading.Thread(target=processSOSofOne, name='sosObjectsFromMSAPI', args=(isTerminated, None))
try:
    #start them
    normalObjectsFromMSAPI.start()
    sosObjectsFromMSAPI.start()
    #check them
    lib.time.sleep(5)
    if not normalObjectsFromMSAPI.isAlive(): raise RuntimeError('normalObjectsFromMSAPI is not alive')
    if not sosObjectsFromMSAPI.isAlive(): raise RuntimeError('sosObjectsFromMSAPI is not alive')
except Exception, err:
    log.error('can\'t start threads: ', str(err))
    sys.exit(2)

log.info(g_name + ' started. Waiting for stop signal...')
try:
    while True: lib.time.sleep(10)
except KeyboardInterrupt:
    log.info(g_name + ' stopping: %s' % (str(sys.argv)))
    sys.exit(0)
except Exception, err:
    log.error(g_name + ' stopping, fatal error: %s' % (str(err)))
    sys.exit(5)
finally:
    try:
        isTerminated.set()
        normalObjectsFromMSAPI.join()
        sosObjectsFromMSAPI.join()
        heartbeat.stop()
        log.info('stopped')
    except Exception, err:
        log.error('error while exiting: %s', str(err))
        sys.exit(4)
